In Chapters 6 and 7 we introduced the basics of C++
classes and the notion of abstract data types (ADTs).
Manipulations on class objects (i.e., instances of ADTs)
were accomplished by sending messages (in the form of
member function calls) to the objects. This function-
call notation is cumbersome for certain kinds of classes,
especially mathematical classes. For these kinds of
classes it would be nice to use C++'s rich set of built-in
operators to specify object manipulations. In this
chapter, we show how to enable C++'s operators to
work with class objects. This process is called <i>operator</i> <br>
</page>
<page>
<i>overloading</i>. It is straightforward and natural to extend
C++ with these new capabilities. It also requires great
care because when overloading is misused it can make a
program difficult to understand.<br>
<spacer width=16 height=1>Operator <b><<</b> has several purposes in C++--as the
stream-insertion operator and as the bitwise left-shift
operator. This is an example of operator overloading.
Similarly, <b>>></b> is also overloaded; it is used both as the
stream-extraction operator and as the bitwise right-shift
operator. Both of these operators are overloaded in the
C++ class library. The C++ language itself overloads <b>+</b>
and <b>-</b>. These operators perform differently depending <br>
</page>
<page>
on their context in integer arithmetic, floating-point
arithmetic, and pointer arithmetic.<br>
<spacer width=16 height=1>C++ enables the programmer to overload most
operators to be sensitive to the context in which they
are used. The compiler generates the appropriate code
based on the manner in which the operator is used.
Some operators are overloaded frequently, especially
the assignment operator and various arithmetic
operators such as <b>+</b> and <b>-</b>. The job performed by
overloaded operators can also be performed by explicit
function calls, but operator notation is often clearer.<br>
<spacer width=16 height=1>We will discuss when to use operator overloading and
when not to use operator overloading. We show how to <br>
</page>
<page>
overload operators, and we present many complete
programs using overloaded operators. <br>
</page>
</section>
<section type=Body name=Default title="8.2 Fundamentals of Operator Overloading">
<page>
<font size=18 bold>8.2 Fundamentals of Operator Overloading</font><hr>
C++ programming is a type-sensitive and type-focused
process. Programmers can use built-in types and can
define new types. The built-in types can be used with
C++'s rich collection of operators. Operators provide
programmers with a concise notation for expressing
manipulations of objects of built-in types. <br>
<spacer width=16 height=1>Programmers can use <a href="^Engineer::c:s0p0"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>operators with user-defined types
as well. Although C++ does not allow new operators to
be created, it does allow most existing operators to be
<a href="^Practice::c:s0p1"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>overloaded so that when these operators are used with
class objects, the operators have meaning appropriate to <br>
</page>
<page>
the new types. This is one of C++'s most powerful
features. <br>
<spacer width=16 height=1>Although <a href="^Practice::c:s0p0"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>operator overloading may sound like an
exotic capability, most programmers implicitly use
overloaded operators regularly. For example, the
addition operator (<b>+</b>) operates quite differently on
integers, floats, and doubles. But addition nevertheless
works fine with variables of type <b>int,</b> <b>float</b>, <b>double</b>, and
a number of other built-in types because the addition
operator (<b>+</b>) has been overloaded in the C++ language
itself. <br>
<spacer width=16 height=1>Operators are overloaded by writing a function
definition (with a header and body) as you normally <br>
</page>
<page>
would, except that the function name now becomes the
keyword <b>operator </b>followed by the symbol for the
operator being overloaded. For example, the function
name <b>operator+</b> would be used to overload the
addition operator (<b>+</b>).<br>
<spacer width=16 height=1>To use an operator on class objects, that operator <i>must</i>
be overloaded--with two exceptions. The assignment
operator (<b>=</b>) may be used with every class without
explicit overloading. The default behavior of the
assignment operator is a <i>memberwise assignment </i>of the
data members of the class. We will soon see that such
default memberwise assignment is dangerous for
classes with pointer members; we will explicitly <br>
</page>
<page>
overload the assignment operator for such classes. The
address operator (<b>&</b>) may also be used with objects of
any class without overloading; it simply returns the
address of the object in memory. The address operator
can also be overloaded. <br>
<spacer width=16 height=1>Overloading is most appropriate for mathematical
classes. These often require that a substantial set of
operators be overloaded to ensure consistency with the
way these mathematical classes are handled in the real
world. For example, it would be unusual to overload
only addition for a complex number class because other
arithmetic operators are also commonly used with
complex numbers.<br>
</page>
<page>
C++ is an operator-rich language. C++ programmers
who understand the meaning and context of each
operator are likely to make reasonable choices when it
comes to overloading operators for new classes.<br>
<spacer width=16 height=1>The point of operator overloading is to provide the
same concise expressions for user-defined types that
C++ provides with its rich collection of <a href="^Practice::c:s0p3"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>operators for
built-in types. Operator overloading is not automatic,
however; the programmer must write operator
overloading functions to perform the desired
operations. Sometimes these functions are best made
member functions; sometimes they are best as <tt><b>friend</b></tt> <br>
</page>
<page>
functions; and occasionally they can be made non-
member, non-<b>friend</b> functions.<br>
<spacer width=16 height=1>Extreme misuses of overloading are possible such as
overloading operator <b>+</b> to perform subtraction-like
operations or overloading <a href="^Practice::c:s0p2"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>operator <b>/</b> to perform
The operator keyword is used when defining new operators. <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
</page>
</section>
<section type=Body name=Default title="8.3 Restrictions on Operator Overloading">
<page>
<font size=18 bold>8.3 Restrictions on Operator Overloading</font><hr>
Most of C++'s operators can be overloaded. These are
shown in <a href="^Illustration::c:s0p1"><img src="bckgrnds/icons/ill_ico.gif" align=sidebar>Fig. 8.1</a>. <a href="^Illustration::c:s0p2"><img src="bckgrnds/icons/ill_ico.gif" align=sidebar>Figure 8.2</a> shows the operators that
cannot be overloaded.<br>
<spacer width=16 height=1>The precedence of an <a href="^Errors::c:s0p0"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>operator cannot be changed by
overloading. This can lead to awkward situations in
which an operator is overloaded in a manner for which
its fixed precedence is inappropriate. However,
parentheses can be used to force the order of evaluation
of overloaded operators in an expression. <br>
The associativity of an operator cannot be changed by
overloading. <br>
</page>
<page>
It is not possible to change the "arity" of an operator
(i.e., the number of operands an operator takes):
Overloaded unary operators remain as unary operators;
overloaded binary operators remain as binary operators.
C++'s only ternary operator (<b>?:</b>) cannot be overloaded
(<a href="^Illustration::c:s0p2"><img src="bckgrnds/icons/ill_ico.gif" align=sidebar>Fig. 8.2</a>). Operators <b>&</b>, <b>*</b>, <b>+</b> and <b>-</b> each have unary and
binary versions; these unary and binary versions can be
overloaded separately.<br>
<spacer width=16 height=1>It is not possible to create new <a href="^Errors::c:s0p1"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>operators; only existing
operators can be overloaded. Unfortunately, this
prevents the programmer from using popular notations
like the <b>**</b> operator used in BASIC for exponentiation <br>
</page>
<page>
The meaning of how an operator works on objects of
built-in types cannot be changed by operator
overloading. The programmer cannot, for example,
change the meaning of how <b>+</b> adds two integers.
<a href="^Practice::c:s0p4"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>Operator <a href="^Errors::c:s0p2"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>overloading works only with objects of user-
defined types or with a mixture of an <a href="^Engineer::c:s0p1"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>object of a user-
defined type and an object of a <a href="^Errors::c:s0p5"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>built-in type. <br>
<spacer width=16 height=1>Overloading an assignment <a href="^Errors::c:s0p3"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>operator and an addition
operator to allow statements like<br>
<font size=2><br></font><font size=11><pre>
object2 = object2 + object1;<p>
</pre></font>
does not imply that the <b>+=</b> operator is also overloaded
to allow statements such as<br>
<font size=2><br></font><font size=11><pre>
object2 += object1;<p>
</pre></font>
</page>
<page>
Such behavior can be achieved by explicitly
overloading the <b>+=</b> operator for that class.<br>
The precedence of an operator cannot be changed by overloading. <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
</page>
</section>
<section type=Body name=Default title="8.4 Operator Functions as Class Members vs. as Friend Functions">
<page>
<font size=18 bold>8.4 Operator Functions as Class Members
vs. as Friend Functions</font><hr>
Operator functions can be member functions or non-
member functions; non-member functions are often
made <tt><b>friends</b></tt> for performance reasons. The member
functions use the <b>this</b> pointer implicitly to obtain one of
their class object arguments. That class argument must
be explicitly listed in a non-member function call.<br>
<spacer width=16 height=1>When overloading <b>()</b>, <b>[]</b>, <b>-></b>, or any of the assignment
operators, the operator overloading function must be
declared as a class member. For the other operators, the <br>
</page>
<page>
operator overloading functions can be non-member
functions. <br>
<spacer width=16 height=1>Whether an operator function is implemented as a
member function or as a non-member function, the
operator is still used the same way in expressions. So
which implementation is best? <br>
<spacer width=16 height=1>When an operator function is implemented as a member
function, the leftmost (or only) operand must be a class
object (or a reference to a class object) of the operator's
class. If the left operand must be an object of a different
class or a built-in type, this operator function must be
implemented as a non-member function (as we will do
in<a href="#s5p0"> Section 8.5</a> when overloading <b><<</b> and <b>>></b> as the <br>
</page>
<page>
stream-insertion and stream-extraction operators,
respectively). A non-member operator function needs
to be a <b>friend</b> if that function must access <b>private</b> or
<b>protected</b> members of that class directly.<br>
<spacer width=16 height=1>The overloaded <b><<</b> operator must have a left operand of
type <b>ostream &</b> (such as <b>cout</b> in the expression <b>cout
<< classObject</b>), so it must be a non-member function.
Similarly, the overloaded <b>>></b> operator must have a left
operand of type <b>istream &</b> (such as <b>cin</b> in the
expression <b>cin >> classObject</b>), so it, too, must be a
non-member function. Also, each of these overloaded
operator functions may require access to the <b>private</b>
data members of the class object being output or input, <br>
</page>
<page>
so these overloaded operator functions are sometimes
made <b>friend</b> <a href="^Perform::c:s0p0"><img src="bckgrnds/icons/perf_ico.gif" align=sidebar></a>functions of the class for performance
reasons.<br>
<spacer width=16 height=1>Operator member functions of a specific class are called
only when the left operand of a binary operator is
specifically an object of that class, or when the single
operand of a unary operator is an object of that class.<br>
<spacer width=16 height=1>Another reason why one might choose a non-member
function to overload an operator is to enable the
operator to be commutative. For example, suppose we
have an object, <b>number</b>, of type <b>long int</b>, and an object
<b>bigInteger1</b>, of class <b>HugeInteger</b> (a class in which
integers may be arbitrarily large rather than being <br>
</page>
<page>
limited by the machine word size of the underlying
hardware; class <b>HugeInteger</b> is developed in the
chapter exercises). The addition operator (<b>+</b>) produces a
temporary <b>HugeInteger object</b> as the sum of a
<b>HugeInteger</b> and a <b>long int</b> (as in the expression
<b>bigInteger1 + number</b>), or as the sum of a <b>long int</b> and
a <b>HugeInteger </b>(as in the expression <b>number +
bigInteger1</b>). Thus, we require the addition operator to
be commutative (exactly as it is normally). The
problem is that the class object must appear on the left
of the addition operator if that operator is to be
overloaded as a member function. So, we overload the
operator as a non-member <b>friend</b> function to allow the <br>
</page>
<page>
<b>HugeInteger</b> to appear on the right of the addition. The
<b>operator+</b> function that deals with the <b>HugeInteger</b> on
the left can still be a member function. Remember that a
non-member function need not necessarily be a <b>friend</b>
if appropriate <i>set</i> and <i>get</i> functions exist in the class's
<tt><b>public</b></tt> interface, and especially if the <i>set</i> and <i>get</i>
functions are <b>inlined</b>.<br>
</page>
<page>
<b>Select the true statement(s). </b><br>
<component type="checkbox" width=20 height=18 label="" name="" feedback="False. Overloaded assignment operators must be declared as member functions.">
Overloaded assignment operators must be declared as non-member functions. <br>
A unary operator for a class can be overloaded as a non-
<b>static</b> member function with no arguments or as a non-
member function with one argument; that argument
must be either an object of the class or a reference to an
object of the class. Member functions that implement
overloaded operators must be non-<b>static</b> so they can
access the non-<b>static</b> data of the class. Remember that
<b>static</b> member functions can only access <b>static</b> data
members of the class.<br>
<spacer width=16 height=1>Later in this chapter, we will overload unary operator <b>!</b>
to test if an object of our <b>String</b> class is empty and <br>
</page>
<page>
return a <b>bool</b> result. When overloading a unary operator
such as <b>!</b> as a non-<b>static</b> member function with no
arguments, if <b>s</b> is a <b>String</b> class object or a reference to
a <b>String</b> class object, when the compiler sees the
expression <b>!s</b> the compiler generates the call
<b>s.operator!()</b>. The operand <b>s</b> is the class object for
which the <b>String</b> class member function <b>operator!</b> is
being invoked. The function is declared in the class
definition as follows:<br>
<font size=2><br></font><font size=11><pre>
class String {<p>
public:<p>
bool operator!() const;<p>
...<p>
};<p>
</pre></font>
</page>
<page>
A unary operator such as <b>!</b> may be overloaded as a non-
member function with one argument two different
ways--either with an argument that is an object (this
requires a copy of the object, so the side effects of the
function are not applied to the original object), or with
an argument that is a reference to an object (no copy of
the original object is made, so all side effects of this
function are applied to the original object). If <b>s</b> is a
<b>String </b> <a href="^Practice::c:s0p5"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>class object (or a reference to a <b>String</b> class
object), then !<b>s </b>is treated as if the call <b>operator!( s )
</b>had been written, invoking the non-member <b>friend</b>
function of class <b>String</b> declared below:<br>
A binary operator can be overloaded as a non-static member function taking one argument. <br>
<component type="checkbox" width=20 height=18 label="" name="" feedback="False. Such a function must take two arguments.">
A binary operator can be overloaded as a non-member function taking one argument. <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
</page>
</section>
<section type=Body name=Default title="8.8 Case Study: An Array Class">
<page>
<font size=18 bold>8.8 Case Study: An Array Class</font><hr>
Array notation in C++ is just an alternative to pointers,
so arrays have much potential for errors. For example, a
program can easily "walk off" either end of an array
because C++ does not check whether subscripts fall
outside the range of an array. Arrays of size <i>n </i>must
number their elements 0, ..., <i>n</i> 1; alternate subscript
ranges are not allowed. An entire array cannot be input
or output at once; each array element must be read or
written individually. Two arrays cannot be
meaningfully compared with equality operators or
relational operators (because the array names are <br>
</page>
<page>
simply pointers to where the arrays begin in memory).
When an array is passed to a general-purpose function
designed to handle arrays of any size, the size of the
array must be passed as an additional argument. One
array cannot be assigned to another with the assignment
operator(s) (because array names are <tt><b>const</b></tt> pointers and
a constant pointer cannot be used on the left side of an
assignment operator). These and other capabilities
certainly seem like "naturals" for dealing with arrays,
but C++ does not provide such capabilities. However,
C++ does provide the means to implement such array
capabilities through the mechanisms of operator
overloading.<br>
</page>
<page>
In this example, we develop an array class that
performs range checking to ensure that subscripts
remain within the bounds of the array. The class allows
one array object to be assigned to another with the
assignment operator. Objects of this array class
automatically know their size so the size does not need
to be passed separately as an argument when passing an
array to a function. Entire arrays can be input or output
with the stream-extraction and stream-insertion
operators, respectively. Array comparisons can be made
with the equality operators <b>==</b> and <b>!=</b>. Our array class
uses a <b>static</b> member to keep track of the number of
array objects that have been instantiated in the program. <br>
</page>
<page>
This example will sharpen your appreciation of data
abstraction. You will probably want to suggest many
enhancements to this array class. Class development is
an interesting, creative, and intellectually challenging
activity--always with the goal of "crafting valuable
classes."<br>
<spacer width=16 height=1>The program of <a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 8.4</a> demonstrates class <b>Array</b> and
its overloaded operators. First we walk through the
driver program in <b>main</b>. Then we consider the class
definition and each of the class's member function and
<tt><b>friend</b></tt> function definitions. <br>
<spacer width=16 height=1>The <tt><b>static</b></tt> class variable <b>arrayCount</b> of class <b>Array</b>
contains the number of <b>Array</b> objects instantiated <br>
</page>
<page>
during program execution. The program begins by
using <b>static</b> member function <b>getArrayCount</b> (line
176) to retrieve the number of arrays instantiated so far.
Next, the program instantiates two objects of class
<b>Array</b> (line 179)--<b>integers1</b> with seven elements and
<b>integers2</b> with default size 10 elements (the default
value specified by the <b>Array</b> default constructor). Line
181 calls function <b>getArrayCount</b> again to retrieve the
value of class variable <b>arrayCount</b>. Lines 184 through
187 use member function <b>getSize</b> to determine the size
of <b>Array integers1</b> and output <b>integers1</b> using the
<b>Array</b> overloaded stream-insertion operator to confirm
that the array elements were initialized correctly by the <br>
</page>
<page>
constructor. Next, lines 190 through 193 output the size
of array <b>integers2</b> and output <b>integers2</b> using the
declare the overloaded stream-insertion operator and
the overloaded stream-extraction operator to be <b>friends</b>
of class <b>Array</b>. When the compiler sees an expression
like <br>
<font size=2><br></font><font size=11><pre>
cout << arrayObject<p>
</pre></font>
it invokes the <b>operator<<</b>( <b>ostream &, const Array
& </b>) function by generating the call <br>
<font size=2><br></font><font size=11><pre>
operator<<( cout, arrayObject )<p>
</pre></font>
When the compiler sees an expression like <br>
</page>
<page>
<font size=2><br></font><font size=11><pre>
cin >> arrayObject<p>
</pre></font>
it invokes the <b>operator>>( istream &, Array & )
</b>function by generating the call<br>
<font size=2><br></font><font size=11><pre>
operator>>( cin, arrayObject )<p>
</pre></font>
We note again that these stream-insertion and stream-
extraction operator functions cannot be members of
class <b>Array</b> because the <b>Array</b> object is always
mentioned on the right side of a stream-insertion
operator and a stream-extraction operator. If these
operator functions were to be members of class <b>Array</b>,
the following awkward statements would have to be
used to output and input an <b>Array</b>:<br>
</page>
<page>
<font size=2><br></font><font size=11><pre>
arrayObject << cout;<p>
arrayObject >> cin;<p>
</pre></font>
Function <b>operator<<</b> (defined at line 151) prints the
number of elements indicated by the <b>size</b> from the array
stored at <b>ptr</b>. Function <b>operator>></b> (defined at line 142)
inputs directly into the array pointed to by <b>ptr</b>. Each of
these operator functions returns an appropriate
reference to enable cascaded output or input statements,
respectively.<br>
<spacer width=16 height=1>The line<br>
<font size=2><br></font><font size=11><pre>
Array( int = 10 ); // default constructor<p>
</pre></font>
</page>
<page>
declares the default constructor for the class and
specifies that the array size defaults to 10 elements.
When the compiler sees a declaration like <br>
<font size=2><br></font><font size=11><pre>
Array integers1( 7 );<p>
</pre></font>
or the equivalent form<br>
<font size=2><br></font><font size=11><pre>
Array integers1 = 7;<p>
</pre></font>
it invokes the default constructor (remember that the
default constructor in this example actually receives a
single <tt><b>int</b></tt> argument that has a default value of 10).
The default constructor (defined at line 47) validates
and assigns the argument to the size data member,
uses new to obtain the space to hold the internal
representation of this array and assigns the pointer <br>
</page>
<page>
returned by new to data member ptr, uses assert to
test that new was successful, increments
arrayCount, then uses a for loop to initialize all the
elements of the array to zero. It is possible to have an
Array class that does not initialize its members if, for
example, these members are to be read at some later
time. But this is considered to be a poor programming
practice. <b>Arrays</b>, and objects in general, should be
maintained at all times in a properly initialized and
consistent state.<br>
<spacer width=16 height=1>Line 13<br>
<font size=2><br></font><font size=11><pre>
Array( const Array & ); // copy constructor<p>
</pre></font>
</page>
<page>
declares a <i>copy constructor</i> (defined at line 60) that
initializes an <b>Array</b> by making a copy of an existing
<b>Array</b> object. Such copying must be done carefully to
avoid the pitfall of leaving both <b>Array</b> objects pointing
to the same dynamically allocated storage, exactly the
problem that would occur with default memberwise
copy. Copy constructors are invoked whenever a copy
of an object is needed such as in call-by-value, when
returning an object by value from a called function, or
when initializing an object to be a copy of another
object of the same class. The copy constructor is called
in a definition when an object of class <b>Array</b> is <br>
</page>
<page>
instantiated and initialized with another object of class
<b>Array</b> as in the following declaration:<br>
<font size=2><br></font><font size=11><pre>
Array integers3( integers1 );<p>
</pre></font>
or the equivalent declaration<br>
<font size=2><br></font><font size=11><pre>
Array integers3 = integers1;<p>
</pre></font>
The <a href="^Errors::c:s0p6"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>copy <a href="^Errors::c:s0p8"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>constructor member function <b>Array</b> uses a
member initializer to copy the <b>size</b> of the array used for
initialization into the <b>size</b> data member, uses <b>new</b> to
obtain the space to hold the internal representation of
this array and assigns the pointer returned by <b>new</b> to
data member <b>ptr</b>, uses <b>assert</b> to test that <b>new</b> was
successful, increments <b>arrayCount</b>, then uses a <b>for</b> <br>
</page>
<page>
loop to copy all the elements of the initializer array into
this array. <br>
<spacer width=16 height=1>Line 14<br>
<font size=2><br></font><font size=11><pre>
~Array(); // destructor<p>
</pre></font>
declares the destructor (defined at line 71) for the class.
The <a href="^Engineer::c:s0p4"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>destructor is invoked automatically when the life
of an object of class <b>Array</b> is terminated. The
destructor uses <b>delete []</b> to reclaim the dynamic storage
allocated by <b>new</b> in the constructor then decrements
<b>arrayCount</b>.<br>
<spacer width=16 height=1>Line 15<br>
<font size=2><br></font><font size=11><pre>
int getSize() const; // return size<p>
</pre></font>
declares a function that reads the size of the array.<br>
</page>
<page>
Line 16<br>
<font size=2><br></font><font size=11><pre>
const Array &operator=( const Array & ); <p>
// assign arrays<p>
</pre></font>
declares the overloaded assignment operator function
for the class. When the compiler sees an expression like<br>
<font size=2><br></font><font size=11><pre>
integers1 = integers2;<p>
</pre></font>
it invokes the <b>operator=</b> function by generating the call<br>
<font size=2><br></font><font size=11><pre>
integers1.operator=( integers2 )<p>
</pre></font>
The <b>operator=</b> <a href="^Engineer::c:s0p6"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>member function (defined at line 82)
tests for <i>self assignment</i>. If a self assignment is being
attempted, the <a href="^Errors::c:s0p10"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>assignment is skipped (i.e., the object
already is itself; in a moment we will see why self-
assignment is dangerous). If it is not a self <a href="^Engineer::c:s0p5"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>assignment, <br>
</page>
<page>
then the member function determines if the sizes of the
two arrays are identical--in which case the original
array of integers in the left-side <b>Array</b> object is not
The preceding <b>operator>=</b> definition uses the
overloaded < operator to determine if one <b>String</b> object
is greater than or equal to another. Note that the
operator <a href="^Engineer::c:s0p9"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>functions for <b>!=</b>, <b>></b>, <b><=</b> and <b>>=</b> are defined in
the header file. The compiler <b>inlines</b> these definitions to
eliminate the overhead of the extra function calls.<br>
</page>
<page>
Lines 38 and 39<br>
<font size=2><br></font><font size=11><pre>
char &operator[]( int ); <p>
// subscript operator<p>
const char &operator[]( int ) const; <p>
// subscript operator<p>
</pre></font>
declare two overloaded subscript operators (defined at
lines 122 and 131)--one for non-<b>const Strings</b> and one
for <b>const Strings</b>. When the compiler sees an
expression like <b>string1[ 0 ]</b>, the compiler generates the
call <b>string1.operator[]( 0 )</b> (using the appropriate
version of <b>operator[]</b> based on whether or not the
<b>String</b> is <b>const</b>). Function <b>operator[]</b> first uses <b>assert</b>
to perform a range check on the <a href="^Debug::c:s0p0"><img src="bckgrnds/icons/dbt_ico.gif" align=sidebar></a>subscript; if the
subscript is out of range, the program will print an error <br>
</page>
<page>
message and terminate abnormally. If the subscript is in
range, the non-<b>const</b> version of <b>operator[]</b> returns as a
<b>char &</b> to the appropriate character of the <b>String</b>
object; this <b>char &</b> may be used as an <i>lvalue</i> to modify
the designated character of the <b>String</b> object. The <b>const</b>
version of <b>operator[]</b> returns <b>const char &</b> to the
appropriate character of the <b>String</b> object; this <b>char &</b>
may be used as an <i>rvalue</i> to read the value of the
character.<br>
<spacer width=16 height=1>Line 40<br>
<font size=2><br></font><font size=11><pre>
String &operator()( int, int ); // return a substring<p>
</pre></font>
declares the <i>overloaded function-call operator</i> (defined
at line 141). In string classes, it is common to overload <br>
</page>
<page>
this operator to select a substring from a <b>String</b> object.
The two integer parameters specify the start location
and the length of the substring being selected from the
<b>String</b>. If the start location is out of range or the
substring length is negative, an error message is
generated. By convention, if the substring length is 0,
then the substring is selected all the way to the end of
the <b>String</b> object. For example, suppose <b>string1</b> is a
<b>String</b> object containing the character string
<b>"AEIOU"</b>. When the compiler sees the expression
<b>string1( 2, 2 )</b>, it generates the call
<b>string1.operator()( 2, 2 )</b>. When this call executes, it
produces a new dynamically allocated <b>String</b> object <br>
</page>
<page>
containing the string <b>"IO"</b> and returns a reference to
this object. <br>
<spacer width=16 height=1>Overloading the function call operator <b>()</b> is powerful
because functions can take arbitrarily long and complex
parameter lists. So we can use this capability for many
interesting purposes. One such use of the function call
operator is an alternate array subscripting notation:
Instead of using C's awkward double square bracket
notation for double arrays such as in a<b>[ b ][ c ]</b>, some
programmers prefer to overload the function call
operator to enable the notation <b>a( b, c )</b>. The overloaded
function call operator can only be a non-<b>static</b> member <br>
</page>
<page>
function. This operator is used only when the "function
name" is an object of class <b>String</b>.<br>
<spacer width=16 height=1>Line 41<br>
<font size=2><br></font><font size=11><pre>
int getLength() const; // return string length<p>
</pre></font>
declares a function that returns the length of the <b>String</b>
object. Note that this function (defined at line 168)
obtains the length by returning the value of the <b>private</b>
data of class <b>String</b>.<br>
<spacer width=16 height=1>At this point, the reader should now step through the
code in <b>main</b>, examine the output window, and check
each use of an overloaded operator.<br>
</page>
</section>
<section type=Body name=Default title="8.11 Overloading ++ and --">
<page>
<font size=18 bold>8.11 Overloading ++ and --</font><hr>
The increment and decrement operators--
preincrement, postincrement, predecrement, and
postdecrement--can all be overloaded. We will see how
the compiler distinguishes between the prefix version
and the postfix version of an increment or decrement
operator.<br>
<spacer width=16 height=1>To overload the increment operator to allow both
preincrement and postincrement usage, each
overloaded operator function must have a distinct
signature so the compiler will be able to determine
which version of <b>++ </b>is intended. The prefix versions are <br>
</page>
<page>
overloaded exactly as any other prefix unary operator
would be. <br>
<spacer width=16 height=1>Suppose, for example, that we want to add 1 to the day
in <b>Date</b> object <b>d1</b>. When the compiler sees the
preincrementing expression<br>
<font size=2><br></font><font size=11><pre>
++d1<p>
</pre></font>
the compiler generates the member function call<br>
<font size=2><br></font><font size=11><pre>
d1.operator++()<p>
</pre></font>
whose prototype would be<br>
<font size=2><br></font><font size=11><pre>
Date &operator++();<p>
</pre></font>
If the preincrementing is implemented as a non-member
function, when the compiler sees the expression<br>
<font size=2><br></font><font size=11><pre>
++d1<p>
</pre></font>
</page>
<page>
the compiler generates the function call<br>
<font size=2><br></font><font size=11><pre>
operator++( d1 )<p>
</pre></font>
whose prototype would be declared in the <b>Date</b> class as <br>
<font size=2><br></font><font size=11><pre>
friend Date &operator++( Date & );<p>
</pre></font>
Overloading the postincrementing operator presents a
bit of a challenge because the compiler must be able to
distinguish between the signatures of the overloaded
preincrement and postincrement operator functions.
The convention that has been adopted in C++ is that
when the compiler sees the postincrementing
expression <br>
<font size=2><br></font><font size=11><pre>
d1++<p>
</pre></font>
it will generate the member-function call<br>
</page>
<page>
<font size=2><br></font><font size=11><pre>
d1.operator++( 0 )<p>
</pre></font>
whose prototype is <br>
<font size=2><br></font><font size=11><pre>
Date operator++( int )<p>
</pre></font>
The 0 is strictly a "dummy value" to make the argument
list of <b>operator++</b> used for postincrementing
distinguishable from the argument list of <b>operator++</b>
used for preincrementing.<br>
<spacer width=16 height=1>If the postincrementing is implemented as a non-
member function, when the compiler sees the
expression<br>
<font size=2><br></font><font size=11><pre>
d1++<p>
</pre></font>
the compiler generates the function call<br>
<font size=2><br></font><font size=11><pre>
operator++(d1, 0)<p>
</pre></font>
</page>
<page>
whose prototype would be<br>
<font size=2><br></font><font size=11><pre>
friend Date operator++( Date &, int );<p>
</pre></font>
Once again, the <b>0</b> argument is used by the compiler so
the argument list of <b>operator++</b> used for
postincrementing is distinguishable from the argument
list for preincrementing.<br>
<spacer width=16 height=1>Everything stated in this section for overloading
preincrement and postincrement operators applies to
overloading predecrement and postdecrement
operators. Next, we examine a <b>Date</b> class with
overloaded preincrement and postincrement operators.<br>
The -- operator can be overloaded for both predecrementing and postdecrementing. <br>
<component type="checkbox" width=20 height=18 label="" name="" feedback="False. The signature for a postincrement member function takes an int as a parameter.">
The signature for a preincrement member function takes an int as a parameter. <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
</page>
</section>
<section type=Body name=Default title="8.12 Case Study: A Date Class">
<page>
<font size=18 bold>8.12 Case Study: A Date Class</font><hr>
<a href="^Code::c:s0p3"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Figure 8.6</a> illustrates a <b>Date</b> class. The class uses
overloaded preincrement and postincrement operators
to add 1 to the day in a <b>Date</b> object, while causing
appropriate increments to the month and year if
necessary.<br>
<spacer width=16 height=1><tt><b>Date</b></tt>'s <b>public</b> interface includes an overloaded
stream-insertion operator, a default constructor, a
<b>setDate</b> function, an overloaded preincrement operator,
an overloaded postincrement operator, an overloaded
addition assignment operator (<b>+=</b>), a function to test for <br>
</page>
<page>
leap years, and a function to determine if a day is the
last day of the month.<br>
The driver program in <b>main</b> creates the date objects <b>d1</b>
which is initialized by default to January 1, 1900; <b>d2</b>
which is initialized to December 27, 1992; and <b>d3</b>
which the program attempts to initialize to an invalid
date. The <b>Date</b> constructor calls <b>setDate</b> to validate the
month, day, and year specified. If the month is invalid,
it is set to 1. An invalid year is set to 1900. An invalid
day is set to 1.<br>
<spacer width=16 height=1>The driver program outputs each of the constructed
<b>Date</b> objects using the overloaded stream-insertion
operator. The overloaded operator <b>+=</b> is used to add 7 <br>
</page>
<page>
days to <b>d2</b>. Then the <b>setDate</b> function is used to set <b>d3</b>
to February 28, 1992. Next, a new <b>Date</b> object, <b>d4</b>, is
set to March 18, 1969. Then <b>d4</b> is incremented by 1
with the overloaded preincrement operator. The date is
printed before and after the preincrementing to confirm
that it worked correctly. Finally, <b>d4</b> is incremented with
the overloaded postincrement operator. The date is
printed before and after the postincrementing to
confirm that it worked correctly.<br>
<spacer width=16 height=1>Overloading the preincrementing operator is
straightforward. The preincrementing operator calls
<b>private</b> utility function <b>helpIncrement</b> to increment
the date. This function deals with "wraparounds" or <br>
</page>
<page>
"carries" that occur when we increment the last day of
the month. These carries require incrementing the
month. If the month is already 12, then the year must
also be incremented. Function <b>helpIncrement</b> uses
functions <b>leapYear</b> and <b>endOfMonth</b> to increment the
day correctly.<br>
<spacer width=16 height=1>The overloaded preincrement operator returns a
reference to the current <b>Date</b> object (i.e., the one that
was just incremented). This occurs because the current
object, <b>*this</b>, is returned as a <b>Date &</b>. <br>
<spacer width=16 height=1>Overloading the postincrement operator is a bit trickier.
To emulate the effect of the postincrement, we must
return an unincremented copy of the <b>Date</b> object. On <br>
</page>
<page>
entry to <b>operator++</b>, we save the current object (<b>*this</b>)
in <b>temp</b>. Next, we call <b>helpIncrement</b> to increment the
current <b>Date</b> object. Then, we return the unincremented
copy of the object previously stored in <b>temp</b>. Note that
this function cannot return a reference to the local <b>Date</b>
object <b>temp</b> because local variables are destroyed when
the function in which they are declared is exited. Thus,
declaring the return type to this function as <b>Date &</b>
would return a reference to an object that no longer
exists. Returning a reference to a local variable is a
common error for which some compilers will issue a
<indent width=8 delay>* Operator << is used for multiple purposes in C++--
as the stream-insertion operator and as the left-shift
operator. This is an example of operator overloading.
Similarly, >> is also overloaded; it is used both as the
stream-extraction operator and as the right-shift operator. </indent>
<indent width=8 delay>* C++ enables the programmer to overload most operators to be sensitive to the context in which they are
used. The compiler generates the appropriate code
based on the manner in which the operator is used. </indent>
<indent width=8 delay>* Operator overloading contributes to C++'s extensi</indent>
</page>
<page>
<indent width=8 delay>* bility.</indent>
<indent width=8 delay>* To overload an operator, write a function definition;
the function name must be the keyword <b>operator</b> followed by the symbol for the operator being overloaded. </indent>
<indent width=8 delay>* To use an operator on class objects, that operator
<i>must</i> be overloaded--with two exceptions. The assignment operator (<b>=</b>) may be used with two objects of the
same class to perform a default memberwise copy without overloading. The address operator (<b>&</b>) may also be
used with objects of any class without overloading; it
returns the address of the object in memory. </indent>
<indent width=8 delay>* Operator overloading provides the same concise
expressions for user-defined types that C++ provides </indent>
</page>
<page>
<indent width=8 delay>* with its rich collection of operators that work on built-
in types.</indent>
<indent width=8 delay>* The precedence and associativity of an operator cannot be changed by overloading. </indent>
<indent width=8 delay>* It is not possible to change the number of operands
an operator takes: Overloaded unary operators remain
as unary operators; overloaded binary operators remain
as binary operators. C++'s only ternary operator, <b>?:</b>,
cannot be overloaded.</indent>
<indent width=8 delay>* It is not possible to create symbols for new operators;
only existing operators may be overloaded. </indent>
<indent width=8 delay>* The meaning of how an operator works on objects of
built-in types cannot be changed by overloading. </indent>
</page>
<page>
<indent width=8 delay>* When overloading <b>()</b>, <b>[]</b>, <b>-></b>, or any assignment operator, the operator overloading function must be declared
as a class member. </indent>
<indent width=8 delay>* Operator functions can be member functions or non-
member functions.</indent>
<indent width=8 delay>* When an operator function is implemented as a member function, the leftmost operand must be a class
object (or a reference to a class object) of the operator's
class. </indent>
<indent width=8 delay>* If the left operand must be an object of a different
class, this operator function must be implemented as a
non-member function.</indent>
<indent width=8 delay>* Operator member functions are called only when the </indent>
</page>
<page>
<indent width=8 delay>* left operand of a binary operator is specifically an
object of that class, or when the single operand of a
unary operator is an object of that class.</indent>
<indent width=8 delay>* One might choose a non-member function to overload an operator in order to enable the operator to be
commutative (i.e., given the proper overloaded operator
definitions, the left argument of an operator can be an
object of another data type). </indent>
<indent width=8 delay>* A unary operator can be overloaded as a non-<b>static</b>
member function with no arguments or as a non-member function with one argument; that argument must be
either an object of a user-defined type or a reference to
an object of a user-defined type.</indent>
</page>
<page>
<indent width=8 delay>* A binary operator can be overloaded as a non-<b>static</b>
member function with one argument, or as a non-member function with two arguments (one of those arguments must be either a class object or a reference to a
class object).</indent>
<indent width=8 delay>* The array subscript operator <b>[]</b> is not restricted for
use only with arrays; it can be used to select elements
from other kinds of ordered container classes such as
linked lists, strings, dictionaries, and so on. Also, subscripts no longer have to be integers; characters or
strings could be used, for example.</indent>
<indent width=8 delay>* A copy constructor is used to initialize an object with
another object of the same class. Copy constructors are </indent>
</page>
<page>
<indent width=8 delay>* also invoked whenever a copy of an object is needed,
such as in call-by-value, and when returning a value
from a called function. In a copy constructor, the object
being copied must be passed in by reference.</indent>
<indent width=8 delay>* The compiler does not automatically know how to
convert between user-defined types and built-in types--
the programmer must explicitly specify how such conversions are to occur. Such conversions can be performed with conversion constructors (i.e., single-
argument constructors) that simply turn objects of other
types into objects of a particular class.</indent>
<indent width=8 delay>* A conversion operator (or cast operator) can be used
to convert an object of one class into an object of </indent>
</page>
<page>
<indent width=8 delay>* another class or into an object of a built-in type. Such a
conversion operator must be a non-<b>static</b> member function; this kind of conversion operator cannot be a
<b>friend</b> function. </indent>
<indent width=8 delay>* A conversion constructor is a single-argument constructor used to convert the argument into an object of
the constructor's class. The compiler can call such a
constructor implicitly.</indent>
<indent width=8 delay>* The assignment operator is the most frequently overloaded operator. It is normally used to assign an object
to another object of the same class, but through the use
of conversion constructors it can also be used to assign
between different classes. </indent>
</page>
<page>
<indent width=8 delay>* If an overloaded assignment operator is not defined,
assignment is still allowed, but it defaults to a memberwise copy of each data member. In some cases this is
acceptable. For objects that contain pointers to dynamically allocated storage, memberwise copy results in two
different objects pointing to the same dynamically allocated storage. When the destructor for either of these
objects is called, the dynamically allocated storage is
released. If the other object then refers to that storage,
the result is undefined.</indent>
<indent width=8 delay>* To overload the increment operator to allow both
preincrement and postincrement usage, each overloaded operator function must have a distinct signature </indent>
</page>
<page>
<indent width=8 delay>* so the compiler will be able to determine which version
of <b>++</b> is intended. The prefix versions are overloaded
exactly as any other prefix unary operator. Providing a
unique signature to the postincrement operator function
is achieved by providing a second argument--which
must be of type <b>int</b>. Actually, the user does not supply a
value for this special integer argument. It is there simply to help the compiler distinguish between prefix and
postfix versions of increment and decrement operators.</indent>
<a href="^Illustration::c:s0p1">Fig. 8.1</a> Operators that can be overloaded.<br>
<a href="^Illustration::c:s0p2">Fig. 8.2</a> Operators that cannot be overloaded.<br>
<a href="^Code::c:s0p0">Fig. 8.3</a> User-defined stream-insertion and stream-extraction operators.<br>
<a href="^Code::c:s0p1">Fig. 8.4</a> Demonstrating an <b>Array</b> class with overloaded operators.<br>
<a href="^Code::c:s0p2">Fig. 8.5</a> Definition of a basic <b>String</b> class.<br>
<a href="^Code::c:s0p3">Fig. 8.6</a> Class <b>Date</b> with overloaded increment operators.<br>
<a href="^Code::c:s0p4">Fig. 8.7</a> Demonstrating class <b>Complex</b>.<br>
<a href="^Code::c:s0p5">Fig. 8.8</a> A user-defined huge integer class.<br>
<br>
</page>
<page>
<font size=18><a href="~audio/Ch08/08fig001.au"><img src="bckgrnds/icons/audio.gif" align=sidebar></a>Figure 8.1 - Operators that can be overloaded.<img src="graphics/ch08/fig08001.gif" ></font><br>
</page>
<page>
<font size=18><a href="~audio/Ch08/08fig002.au"><img src="bckgrnds/icons/audio.gif" align=sidebar></a>Figure 8.2 - Operators that cannot be overloaded.<img src="graphics/ch08/fig08002.gif" ></font><br>
a) Suppose <b>a</b> and <b>b</b> are integer variables and we form the sum <b>a + b</b>. Now
suppose <b>c</b> and <b>d</b> are floating-point variables and we form the sum <b>c + d</b>. The two
<b>+ </b>operators here are clearly being used for different purposes. This is an example
of ________.<br>
b) The keyword ________ introduces an overloaded operator function
definition.<br>
c) To use operators on class objects, they must be overloaded with the exception
of the operators ________ and ________.<br>
d) The ________, ________ and ________ of an operator cannot be
changed by overloading the operator.<br>
<foreign name="answers" url="^Answers::c:s0p0">
</page>
<page pagename="Exercise 8.2">
<b>Exercise 8.2</b><br>
Explain the multiple meanings of the operators<b> <<</b> and <b>>></b> in C++.<br>
<foreign name="answers" url="^Answers::c:s0p1">
</page>
<page pagename="Exercise 8.3">
<b>Exercise 8.3</b><br>
In what context might the name <b>operator/</b> be used in C++?<br>
<foreign name="answers" url="^Answers::c:s0p2">
<br>
</page>
<page pagename="Exercise 8.4">
<b>Exercise 8.4</b><br>
(True/False) In C++, only existing operators can be overloaded.<br>
<foreign name="answers" url="^Answers::c:s0p3">
<br>
</page>
<page pagename="Exercise 8.5">
<b>Exercise 8.5</b><br>
How does the precedence of an overloaded operator in C++ compare with the
precedence of the original operator?<br>
<foreign name="answers" url="^Answers::c:s0p4">
</page>
<page pagename="Exercise 8.6">
<b>Exercise 8.6</b><br>
Give as many examples as you can of operator overloading implicit in C++.
Give a reasonable example of a situation in which you might want to overload
an operator explicitly in C++.<br>
<br>
<br>
</page>
<page pagename="Exercise 8.7">
<b>Exercise 8.7</b><br>
The C++ operators that cannot be overloaded are ____, ____, ____, ____,
and ____.<br>
<br>
</page>
<page pagename="Exercise 8.8">
<b>Exercise 8.8</b><br>
String concatenation requires two operands--the two strings that are to be
concatenated. In the text we showed how to implement an overloaded
concatenation operator that concatenates the second <b>String</b> object to the right of
the first <b>String</b> object, thus modifying the first <b>String</b> object. In some
applications, it is desirable to produce a concatenated <b>String</b> object without
modifying the <b>String</b> arguments. Implement <b>operator+</b> to allow operations such
as<br>
<font size=2><br></font><font size=11><pre>
string1 = string2 + string3;<p>
</pre></font>
<br>
</page>
<page pagename="Exercise 8.9">
<b>Exercise 8.9</b><br>
<i>(Ultimate operator overloading exercise) </i>To appreciate the care that should go
into selecting operators for overloading, list each of C++'s overloadable
operators and for each list a possible meaning (or several, if appropriate) for
each of several classes you have studied in this course. We suggest you try:<br>
a) Array<br>
b) Stack<br>
c) String<br>
After doing this, comment on which operators seem to have meaning for a wide
variety of classes. Which operators seem to be of little value for overloading?
Which operators seem ambiguous?<br>
<br>
</page>
<page pagename="Exercise 8.10">
<b>Exercise 8.10</b><br>
Now work the process described in the previous problem in reverse. List each of
C++'s overloadable operators. For each, list what you feel is perhaps the
"ultimate operation" the operator should be used to represent. If there are several
excellent operations, list them all.<br>
<br>
</page>
<page pagename="Exercise 8.11">
<b>Exercise 8.11</b><br>
<i>(Project)</i> C++ is an evolving language, and new languages are always being
developed. What additional operators would you recommend adding to C++ or
to a future language like C++ that would support both procedural programming
and object-oriented programming? Write a careful justification. You might
consider sending your suggestions to the ANSI C++ Committee. <br>
<br>
<br>
</page>
<page pagename="Exercise 8.12">
<b>Exercise 8.12</b><br>
One nice example of overloading the function call operator <b>()</b> is to allow the
more common form of double-array subscripting. Instead of saying<br>
<font size=2><br></font><font size=11><pre>
chessBoard[ row ][ column ]<p>
</pre></font>
for an array of objects, overload the function call operator to allow the alternate
form <br>
<font size=2><br></font><font size=11><pre>
chessBoard( row, column )<p>
</pre></font>
<foreign name="answers" url="^Answers::c:s0p5">
</page>
<page pagename="Exercise 8.13">
<b>Exercise 8.13</b><br>
Create a class <b>DoubleSubscriptedArray</b> that has similar features to class
<b>Array</b> in <a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 8.4</a>. At construction time, the class should be able to create an
array of any number of rows and any number of columns. The class should
supply <b>operator()</b> to perform double subscripting operations. For example, in a
3-by-5 <b>DoubleSubscriptedArray</b> called <b>a</b>, the user could write <b>a( 1, 3 )</b> to
access the element at row <b>1</b> and column <b>3</b>. Remember that <b>operator()</b> can
receive any number of arguments (see class <b>String</b> in Fig. 18.5 for an example
of <tt><b>operator()</b></tt>). The underlying representation of the double-subscripted array
should be a single-subscripted array of integers with <i>rows * columns</i> number of
elements. Function <b>operator()</b> should perform the proper pointer arithmetic to
access each element of the array. There should be two versions of <b>operator()</b>--<br>
</page>
<page pagename="Exercise 8.13">
one that returns <b>int &</b> so an element of a <b>DoubleSubscriptedArray </b>can be used
as an <i>lvalue</i> and one that returns <b>const int &</b> so an element of a <b>const
DoubleSubscriptedArray</b> can be used as an <i>rvalue</i>. The class should also
provide the following operators: <b>==</b>, <b>!=</b>, <b>=</b>, <b><<</b> (for outputting the array in row
and column format) and <b>>></b> (for inputting the entire array contents).<br>
<br>
</page>
<page pagename="Exercise 8.14">
<b>Exercise 8.14</b><br>
Overload the subscript operator to return the largest element of a collection, the
second largest, the third largest, etc.<br>
<br>
<br>
</page>
<page pagename="Exercise 8.15">
<b>Exercise 8.15</b><br>
Consider class <b>Complex</b> shown in <a href="^Code::c:s0p4"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 8.7</a>. The class enables operations on so-
called <i>complex numbers</i>. These are numbers of the form <b>realPart +
imaginaryPart *</b> <i>i</i> where <i>i</i> has the value:<img src="graphics/ch08/ex08015.gif" ><br>
a) Modify the class to enable input and output of complex numbers through the
overloaded <b>>></b> and <b><<</b> operators, respectively (you should remove the print
function from the class).<br>
b) Overload the multiplication operator to enable multiplication of two complex
numbers as in algebra.<br>
c) Overload the <b>==</b> and <b>!=</b> operators to allow comparisons of complex numbers.<br>
<foreign name="answers" url="^Answers::c:s0p6">
</page>
<page pagename="Exercise 8.16">
<b>Exercise 8.16</b><br>
A machine with 32-bit integers can represent integers in the range of
approximately 2 billion to +2 billion. This fixed-size restriction is rarely
troublesome. But there are applications in which we would like to be able to use
a much wider range of integers. This is what C++ was built to do, namely create
powerful new data types. Consider class <b>HugeInt</b> of <a href="^Code::c:s0p5"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 8.8</a>. Study the class
carefully, then<br>
a) Describe precisely how it operates.<br>
b) What restrictions does the class have?<br>
c) Overload the <b>*</b> multiplication operator.<br>
d) Overload the <b>/</b> division operator.<br>
e) Overload all the relational and equality operators.<br>
</page>
<page pagename="Exercise 8.17">
<b>Exercise 8.17</b><br>
Create a class <b>RationalNumber</b> (fractions) with the following capabilities:<br>
a) Create a constructor that prevents a 0 denominator in a fraction, reduces or
simplifies fractions that are not in reduced form, and avoids negative
denominators.<br>
b) Overload the addition, subtraction, multiplication and division operators for
this class.<br>
c) Overload the relational and equality operators for this class.<br>
<br>
<br>
</page>
<page pagename="Exercise 8.18">
<b>Exercise 8.18</b><br>
Study the C string-handling library functions and implement each of the
functions as part of the <b>String</b> class. Then, use these functions to perform text
manipulations.<br>
<br>
</page>
<page pagename="Exercise 8.19">
<b>Exercise 8.19</b><br>
Develop class <b>Polynomial</b>. The internal representation of a <b>Polynomial</b> is an
array of terms. Each term contains a coefficient and an exponent. The term<img src="graphics/ch08/ex08019.gif" ><br>
has a coefficient of 2 and an exponent of 4. Develop a full class containing
proper constructor and destructor functions as well as <i>set</i> and <i>get</i> functions. The
class should also provide the following overloaded operator capabilities:<br>
a) Overload the addition operator (<b>+</b>) to add two <b>Polynomials</b>.<br>
b) Overload the subtraction operator (<b>-</b>) to subtract two <b>Polynomials</b>.<br>
c) Overload the assignment operator to assign one <b>Polynomial</b> to another.<br>
d) Overload the multiplication operator (<b>*</b>) to multiply two <b>Polynomials</b>.<br>
<foreign name="answers" url="^Answers::c:s0p7">
</page>
<page pagename="Exercise 8.19">
e) Overload the addition assignment operator (<b>+=</b>), the subtraction assignment
operator <p>
(<b>-=</b>), and the multiplication assignment operator (<b>*=</b>).<br>
<foreign name="answers" url="^Answers::c:s0p7">
</page>
<page pagename="Exercise 8.20">
<b>Exercise 8.20</b><br>
The program of <a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 8.3</a> contains the comment<br>